
package com.shiku.utils;


import java.awt.Graphics2D;
import java.awt.RenderingHints;
import java.awt.geom.AffineTransform;
import java.awt.image.BufferedImage;
import java.awt.image.ColorModel;
import java.awt.image.WritableRaster;


public class ImageHelper {
    public static final String path = System.getProperty("user.dir");


    public static BufferedImage thumb(BufferedImage source, int width, int height, boolean b) {

        int type = source.getType();

        BufferedImage target = null;

        double sx = width / source.getWidth();

        double sy = height / source.getHeight();


        if (b) {

            if (sx > sy) {

                sx = sy;

                width = (int) (sx * source.getWidth());

            } else {

                sy = sx;

                height = (int) (sy * source.getHeight());

            }

        }


        if (type == 0) {

            ColorModel cm = source.getColorModel();

            WritableRaster raster = cm.createCompatibleWritableRaster(width, height);


            boolean alphaPremultiplied = cm.isAlphaPremultiplied();

            target = new BufferedImage(cm, raster, alphaPremultiplied, null);

        } else {

            target = new BufferedImage(width, height, type);

        }
        Graphics2D g = target.createGraphics();


        g.setRenderingHint(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY);


        g.drawRenderedImage(source, AffineTransform.getScaleInstance(sx, sy));

        g.dispose();

        return target;

    }


    public static int rgbToGray(int pixels) {

        int _red = pixels >> 16 & 0xFF;

        int _green = pixels >> 8 & 0xFF;

        int _blue = pixels & 0xFF;

        return (int) (0.3D * _red + 0.59D * _green + 0.11D * _blue);

    }


    public static int average(int[] pixels) {

        float m = 0.0F;

        for (int i = 0; i < pixels.length; i++) {

            m += pixels[i];

        }

        m /= pixels.length;

        return (int) m;

    }


    public static int hammingDistance(String sourceHashCode, String hashCode) {

        int difference = 0;

        int len = sourceHashCode.length();


        for (int i = 0; i < len; i++) {

            if (sourceHashCode.charAt(i) != hashCode.charAt(i)) {

                difference++;

            }

        }


        return difference;

    }


    public static String produceFingerPrint(String filename) {

        BufferedImage source = null;


        int width = 8;

        int height = 8;


        BufferedImage thumb = thumb(source, width, height, false);


        int[] pixels = new int[width * height];

        for (int i = 0; i < width; i++) {

            for (int m = 0; m < height; m++) {

                pixels[i * height + m] = rgbToGray(thumb.getRGB(i, m));

            }

        }


        int avgPixel = average(pixels);


        int[] comps = new int[width * height];

        for (int j = 0; j < comps.length; j++) {

            if (pixels[j] >= avgPixel) {

                comps[j] = 1;

            } else {

                comps[j] = 0;

            }

        }


        StringBuffer hashCode = new StringBuffer();

        for (int k = 0; k < comps.length; k += 4) {

            int result = comps[k] * (int) Math.pow(2.0D, 3.0D) + comps[k + 1] * (int) Math.pow(2.0D, 2.0D) + comps[k + 2] * (int) Math.pow(2.0D, 1.0D) + comps[k + 2];

            hashCode.append(binaryToHex(result));

        }


        return hashCode.toString();

    }


    private static char binaryToHex(int binary) {

        char ch = ' ';

        switch (binary) {
            case 0:

                ch = '0';


                return ch;
            case 1:
                ch = '1';
                return ch;
            case 2:
                ch = '2';
                return ch;
            case 3:
                ch = '3';
                return ch;
            case 4:
                ch = '4';
                return ch;
            case 5:
                ch = '5';
                return ch;
            case 6:
                ch = '6';
                return ch;
            case 7:
                ch = '7';
                return ch;
            case 8:
                ch = '8';
                return ch;
            case 9:
                ch = '9';
                return ch;
            case 10:
                ch = 'a';
                return ch;
            case 11:
                ch = 'b';
                return ch;
            case 12:
                ch = 'c';
                return ch;
            case 13:
                ch = 'd';
                return ch;
            case 14:
                ch = 'e';
                return ch;
            case 15:
                ch = 'f';
                return ch;
        }
        ch = ' ';
        return ch;

    }

}


